package gui;

import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;

import javax.swing.event.MouseInputAdapter;
import javax.swing.Timer;

import card.Card;

import command.Command;
import command.CommandBroadcaster;
import command.CommandGenerator;
import effect.Effect;
import effect.Effect.TargetType;



/**
 * 
 * @author Anton
 * Reacts to mouse events within the CenterPanel, and acts accordingly
 */
public class CenterPanelMapListener extends MouseInputAdapter implements ActionListener{
	
	Timer Mouseovertimer = new Timer(50, (ActionListener) this);
	Point latestPoint = new Point(0,0);
	Point currentPoint = new Point(0,0);
	private SelectionController selectionController = SelectionController.getInstance();
	private boolean dragging=false;
	private Point lastDragPosition = new Point(0, 0);
	//TODO in work
	
	public CenterPanelMapListener(){
		Mouseovertimer.start();
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if(e.getButton()==MouseEvent.BUTTON1){			
			switch(GUICore.getInstance().selectionStatus){
			case NO_SELECTION:
				//Check if a tile is hit, and select the tile
				for(GUITile t : GUICore.getInstance().getAllGUITiles()){
					if(t.contains(e.getX(), e.getY())){
						selectionController.select(t);												
					}
				}
				break;
			case SELECTIONSPHERE:
				for(SelectionSphere s : GUICore.getInstance().selectionSpheres){
					if(s.contains(e.getX(), e.getY())){
						selectionController.select(s);
						break;
					}
				}
				break;		
			case CARD_SELECTED:
				Command c = null;
				// Check if you clicked a tile.
				for(GUITile t : GUICore.getInstance().getAllGUITiles()){
					if(t.contains(e.getX(), e.getY())){		
						// Attempt to create and execute a command generated with the previously selected card and this selected tile
						try{
							c = CommandGenerator.getInstance().generateCommand(GUICore.getInstance().getSelectedCard(), t);
							sendCommand(c);
								
						}catch(Exception e1 )
						{
							e1.printStackTrace();
							System.out.println("Wrongly formatted command.");
						}
										
					}
				}
				
				// Check all actions on the SelectedBar.
				SelectionSphere selectedSphere = null;
				for(SelectionSphere s : SelectedBar.getInstance().getSelectionSpheres()){	
					if(s.contains(e.getX(), e.getY())){ // A sphere is pressed
						selectedSphere = s;
					}
				}
				if(selectedSphere != null){
					if(selectedSphere instanceof ClaimTileSphere){
						c = CommandGenerator.getInstance().generateClaimTileCommand(GUICore.getInstance().getSelectedCard());						
						sendCommand(c);
					}
					if(selectedSphere instanceof EffectSphere){
						EffectSphere effectSphere = (EffectSphere)selectedSphere;
						if(effectSphere.getEffect().isTargetType(TargetType.none)){
							c = CommandGenerator.getInstance().generateActivateEffectCommand(effectSphere.getEffect());
							sendCommand(c);
						}
						else{
							System.out.println("WOOT");
							selectionController.select(effectSphere.getEffect());
						}
					}
				}
				break;
			case EXPECT_INPUT_TILE:
				for(GUITile t : GUICore.getInstance().getAllGUITiles()){
					if(t.contains(e.getX(), e.getY())){
						System.out.println("WOOT");
						c = CommandGenerator.getInstance().generateActivateEffectCommand(GUICore.getInstance().getSelectedEffect(), t);
						sendCommand(c);											
					}
				}
				break;
			}
		}
		else if(e.getButton()==MouseEvent.BUTTON3){ //rightclick
			selectionController.deselect();
		}
		
	}
	
	/**
	 * Sends the command.
	 * Deselects if command is null
	 * @param c
	 */
	private void sendCommand(Command c){
		if(c != null)
			CommandBroadcaster.sendCommand(c);
		else{
			System.out.println("No command was generated");
			selectionController.deselect();
		}
			
	}	
	
	
	/**
	 * Moves map
	 */
	public void mouseDragged(MouseEvent ev){
		if(dragging==false){
			dragging=true;
			lastDragPosition=ev.getPoint();
		}
		Point dOffset=new Point(ev.getX()-lastDragPosition.x, ev.getY()-lastDragPosition.y);
		Point oldOffset=GUICore.getInstance().getMapOffset();
		GUICore.getInstance().setMapOffset(new Point(oldOffset.x+dOffset.x, oldOffset.y+dOffset.y));
		lastDragPosition=ev.getPoint();
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Write or remove?

	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Write or remove

	}
	@Override
	public void mouseMoved(MouseEvent e) {
		currentPoint = getPoint(e); 		
		}
	
	

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// means you're not dragging anymore
		dragging=false;
	
	}

	
		
	public Point getPoint(MouseEvent e){
		return new Point(e.getX(),e.getY());
	}

	/**
	 * Called by the timer.
	 */
	public void actionPerformed(ActionEvent e) {
		if(latestPoint.equals(currentPoint)){
	 		for(SelectionSphere s : GUICore.getInstance().selectionSpheres){
				if(s.contains(latestPoint.x,latestPoint.y)){
					SelectionSphere sphereToShow = s;
					Card cardToShow = sphereToShow.getCard();
					CardViewPanel.getInstance().setShownCard(cardToShow);
				}
	 		}
	 		for(SelectionSphere s : SelectedBar.getInstance().selectionSpheres){
				if(s.contains(latestPoint.x,latestPoint.y)){
					if(s instanceof EffectSphere){
						EffectSphere sphereToShow = (EffectSphere) s;
						Effect effectToShow = sphereToShow.getEffect();
						EffectPopupInfo.getInstance().setProperties(effectToShow);
					}
				}else{
					//EffectPopupInfo.getInstance().setProperties(null, " ");
				}
	 		}
	 	}
		latestPoint = currentPoint;
	}

}
	

